<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.2.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/favicon.ico">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon.ico">
  <link rel="mask-icon" href="/images/favicon.ico" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"wwwttttj.gitee.io","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
  </script>

  <meta name="description" content="java 8 新特性completableFuture 异步编程（多线程并发）最近看到Rxjava 时候看到了java8的新特性competableFuture类，学习了一下。以下做个总结： completableFutrue 特性1. completableFutrue 实现了future&lt;T&gt;接口,completionStage&lt;U&gt;两个接口 future 接口是jdk">
<meta property="og:type" content="article">
<meta property="og:title" content="completable_异步编程">
<meta property="og:url" content="https://wwwttttj.gitee.io/2020/09/24/completable-%E5%BC%82%E6%AD%A5%E7%BC%96%E7%A8%8B/index.html">
<meta property="og:site_name" content="wwwblog">
<meta property="og:description" content="java 8 新特性completableFuture 异步编程（多线程并发）最近看到Rxjava 时候看到了java8的新特性competableFuture类，学习了一下。以下做个总结： completableFutrue 特性1. completableFutrue 实现了future&lt;T&gt;接口,completionStage&lt;U&gt;两个接口 future 接口是jdk">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2020-09-24T02:38:45.000Z">
<meta property="article:modified_time" content="2020-09-24T02:39:28.396Z">
<meta property="article:author" content="wwwttttj">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="https://wwwttttj.gitee.io/2020/09/24/completable-%E5%BC%82%E6%AD%A5%E7%BC%96%E7%A8%8B/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>completable_异步编程 | wwwblog</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

<link rel="alternate" href="/atom.xml" title="wwwblog" type="application/atom+xml">
</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">wwwblog</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
        <li class="menu-item menu-item-commonweal">

    <a href="/404/" rel="section"><i class="fa fa-heartbeat fa-fw"></i>公益 404</a>

  </li>
  </ul>
</nav>




</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://wwwttttj.gitee.io/2020/09/24/completable-%E5%BC%82%E6%AD%A5%E7%BC%96%E7%A8%8B/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="wwwttttj">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="wwwblog">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          completable_异步编程
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>
              

              <time title="创建时间：2020-09-24 10:38:45 / 修改时间：10:39:28" itemprop="dateCreated datePublished" datetime="2020-09-24T10:38:45+08:00">2020-09-24</time>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h1 id="java-8-新特性completableFuture-异步编程（多线程并发）"><a href="#java-8-新特性completableFuture-异步编程（多线程并发）" class="headerlink" title="java 8 新特性completableFuture 异步编程（多线程并发）"></a>java 8 新特性completableFuture 异步编程（多线程并发）</h1><p>最近看到Rxjava 时候看到了java8的新特性competableFuture类，学习了一下。以下做个总结：</p>
<h2 id="completableFutrue-特性"><a href="#completableFutrue-特性" class="headerlink" title="completableFutrue 特性"></a>completableFutrue 特性</h2><pre><code>1. completableFutrue 实现了future&lt;T&gt;接口,completionStage&lt;U&gt;两个接口
future 接口是jdk1.5  新增 用来获取返回值。
completionStage 中文意思 完成阶段。表达的是对执行后的结果进行再次操作。里面拥有许多lambda 表达式进行方便运算（方法后面带async 都是异步执行的） 如
  thenApply(Function&lt;? super T&gt; action) 增强(补充) supplied action
 thenAccept（Consumer&lt;? super T&gt;action) 消耗
 thenRuns(Runable run) 跑一个新的任务
 thenCombine(CompletionStage&lt;? extend U&gt; other,BiFunction&lt;? super T,?super U,? extend v&gt; fn)  返回组合两个任务
 thenAcceptBoth(CompletionStage&lt;? extend U&gt; other,BiFunction&lt;? super T,?super U,? extend v&gt; fn） 消耗两个
 whenComplete（BiConsumer&lt;? super T&gt; action); 返回最后完成的任务。
 还有一些 acceptEitherAsync ,handle,exceptionally 等。这些方法都有最后带async 的方法。使用很方便。</code></pre>
<a id="more"></a>
<h2 id="completablefuture-拥有-以下静态方法"><a href="#completablefuture-拥有-以下静态方法" class="headerlink" title="completablefuture 拥有 以下静态方法"></a>completablefuture 拥有 以下静态方法</h2><pre><code>以下方法不指定executorPool,则会使用默认的ForkJoinPool#commonPool()连接池</code></pre>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">CompletableFuture.supplyAsync() 里面参数 增加lambda 表达式 有返回值</span><br><span class="line">CompletableFuture.runAsync()  异步执行一些方法  无返回值</span><br><span class="line">CompletableFuture.allOf()   所有线程都执行完成后结束</span><br><span class="line">CompletableFuture.anyOf()      只要一个线程执行完成就结束</span><br><span class="line">CompletableFuture.completedFuture()  Returns a new CompletableFuture that is already completed with the given value.</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">  列如：</span><br><span class="line">1.  CompletableFuture.supplyAsync(()-&gt;&quot;hello&quot;).thenApply(s-&gt;s+&quot; world&quot;).join;</span><br><span class="line">  返回值为：hello world;</span><br><span class="line">     </span><br><span class="line">  &#x2F;&#x2F;单任务使用</span><br><span class="line">2. CompletableFuture&lt;T&gt;  oneResult  &#x3D;  CompletableFuture.supplyAsync(() -&gt; oneService.doSomething, executorService) ;</span><br><span class="line">  T t&#x3D;oneResult.get();&#x2F;&#x2F;阻塞获取结果 可以加 一个超时时间 仍timeoutException </span><br><span class="line">  </span><br><span class="line">3.  多任务使用</span><br><span class="line">  &#x2F;&#x2F;1.自定义线程池</span><br><span class="line">    ExecutorService executorService &#x3D; Executors.newFixedThreadPool(10);</span><br><span class="line">     List&lt;CompletableFuture&gt; list&#x3D;new ArrayList&lt;&gt;();</span><br><span class="line"> &#x2F;&#x2F;2.新建 CompletableFuture future任务</span><br><span class="line">CompletableFuture&lt;T&gt;  oneResult&#x3D;  CompletableFuture.supplyAsync(() -&gt; oneService.doSomething, executorService).thenComplete((e,v)-&gt;System.out.println(&quot;hello,world&quot;)) ;</span><br><span class="line">list.add(oneResult);</span><br><span class="line">   CompletableFuture&lt;T&gt;  twoResult&#x3D;  CompletableFuture.supplyAsync(() -&gt; twoService.doSomething, executorService).thenComplete((e,v)-&gt;System.out.println(&quot;hello,world&quot;)) ;</span><br><span class="line">    list.add(twoResult);</span><br><span class="line">   &#x2F;&#x2F;3,将future任务转为数组join</span><br><span class="line">     CompletableFuture.allOf(list.stream().toArray(CompletableFuture[]::new))</span><br><span class="line">                   .join(); 这里会一起执行完成调用thenComplete方法(可以异步执行其他方法)。</span><br><span class="line">  </span><br><span class="line">4.异常处理</span><br><span class="line">         异步任务中如果出现异常情况</span><br><span class="line">         单任务如果get()没有设置超时时间，一直会阻塞的获取。  </span><br><span class="line">         对应单任务可以 返回一个异常信息。</span><br><span class="line">         try&#123;</span><br><span class="line">         do...</span><br><span class="line">         &#125;catch(Exception e)&#123;</span><br><span class="line">           completableFuture.completeExceptionally(e);</span><br><span class="line">         &#125; </span><br><span class="line">                 </span><br><span class="line">        对于多任务，一个任务出现 CompletionException,则最后join结果会报CompletionException异常。thenComplete方法可以收集异常进行处理</span><br><span class="line">        也可以最后处理。</span><br><span class="line">        </span><br><span class="line">                   </span><br><span class="line">          </span><br></pre></td></tr></table></figure>
<p> //与其他   Futrue,FutureTask,CompletionService,CountDownLatch 比较</p>
<p> jdk1.5  futrue 接口  异步线程返回结果集<br> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">ExecutorService executorService &#x3D; Executors.newFixedThreadPool(10);</span><br><span class="line">  Future&lt;Integer&gt; result &#x3D; executorService.submit(() -&gt; &#123;</span><br><span class="line">      System.out.println(&quot;开始执行&quot;);</span><br><span class="line">      return 1;</span><br><span class="line"> </span><br><span class="line">  &#125;);</span><br><span class="line">  result.get(); 阻塞获取，多任务情况 先get先获取</span><br><span class="line">  </span><br><span class="line">  对多任务不够灵活，单任务缺少lambda表达式，看情况使用了。</span><br><span class="line">  </span><br></pre></td></tr></table></figure><br>  jdk1.5   FutureTask   类  增强型Future 可以取消任务。Future,Runnable的实现类</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">public static void main(String[] args) throws Exception&#123;</span><br><span class="line">     FutureTask&lt;Integer&gt; futureTask1&#x3D;new FutureTask&lt;&gt;(new doOneThing());</span><br><span class="line">          &#x2F;&#x2F;做第一件事1秒</span><br><span class="line">          futureTask1.run();&#x2F;&#x2F;这里和主线程同步执行</span><br><span class="line">          &#x2F;&#x2F;主线程执行其他任务3秒</span><br><span class="line">          Thread.sleep(3000);</span><br><span class="line">          System.out.println(&quot;主线程结束&quot;);</span><br><span class="line">          System.out.println(futureTask1.get());&#x2F;&#x2F;这边的get是阻塞是获取</span><br><span class="line">      &#125; </span><br><span class="line">      public static class doOneThing implements Callable&lt;Integer&gt;&#123;</span><br><span class="line">      </span><br><span class="line">          @Override</span><br><span class="line">          public Integer call() throws Exception &#123;</span><br><span class="line">      </span><br><span class="line">              System.out.println(&quot;###########开始做第一件事开始&quot;);</span><br><span class="line">              Thread.sleep(1000);</span><br><span class="line">              System.out.println(&quot;###########开始做第一件事完成&quot;);</span><br><span class="line">              return 1;</span><br><span class="line">          &#125;</span><br><span class="line">      &#125;</span><br><span class="line">   日志结果：   </span><br><span class="line">     &#x2F;&#x2F; ###########开始做第一件事开始</span><br><span class="line">     &#x2F;&#x2F; ###########开始做第一件事完成</span><br><span class="line">      &#x2F;&#x2F;主线程结束</span><br><span class="line">   &#x2F;&#x2F;&#x2F;   1  </span><br><span class="line">      可以看出FutureTask 是Future 的一个升级。</span><br><span class="line">      可以穿插其他业务。降低响应时间。</span><br><span class="line">      jdk1.8以前版本的话,有需求的可以使用。</span><br><span class="line">       </span><br></pre></td></tr></table></figure>
<p>jdk1.8  CompletionService，实现类 ExecutorCompletionService 可以加一个(线程池)<br>内部使用LinkedBlockingQueue 维护顺序 +futureTask 接口 ,优先完成后,take()方法获取结果 get()取值</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">public static void main(String[] args) throws Exception&#123;</span><br><span class="line">      ExecutorService executorService &#x3D; Executors.newFixedThreadPool(10);</span><br><span class="line">      ExecutorCompletionService&lt;Integer&gt; service &#x3D; new ExecutorCompletionService&lt;&gt;(executorService);</span><br><span class="line">      for ( int i &#x3D; 1; i &lt; 4; i++) &#123;</span><br><span class="line">          service.submit(new doOneThing(i*1000));</span><br><span class="line">      &#125;</span><br><span class="line">      for ( int i &#x3D; 1; i &lt; 4; i++) &#123;</span><br><span class="line">          Integer integer &#x3D; service.take().get();</span><br><span class="line">          System.out.println(integer);</span><br><span class="line">      &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  public static class doOneThing implements Callable&lt;Integer&gt;&#123;</span><br><span class="line">          int i&#x3D;0;</span><br><span class="line">          public doOneThing(int i)&#123;</span><br><span class="line">              super();</span><br><span class="line">              this.i&#x3D;i;</span><br><span class="line">          &#125;</span><br><span class="line">      @Override</span><br><span class="line">      public Integer call() throws Exception &#123;</span><br><span class="line">  </span><br><span class="line">          System.out.println(&quot;###########开始做第&quot;+i&#x2F;1000+&quot;件事开始&quot;);</span><br><span class="line">          Thread.sleep(i);</span><br><span class="line">          System.out.println(&quot;###########开始做第&quot;+i&#x2F;1000+&quot;件事完成&quot;);</span><br><span class="line">          return i;</span><br><span class="line">      &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  结果：</span><br><span class="line">  ###########开始做第2件事开始</span><br><span class="line">  ###########开始做第3件事开始</span><br><span class="line">  ###########开始做第1件事开始</span><br><span class="line">  ###########开始做第1件事完成</span><br><span class="line">  1000</span><br><span class="line">  ###########开始做第2件事完成</span><br><span class="line">  2000</span><br><span class="line">  ###########开始做第3件事完成</span><br><span class="line">  3000</span><br><span class="line"></span><br><span class="line">   从结果可以看出这个类可以并发执行某些任务。同时按照完成的先后顺序返回结果。有这种需求的可以使用</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>最后 讲讲jdk1.5的 countDownLatch (CyclicBarrier 类似) 这个类可以设定一个值，可以开始多任务,每完成一个值(countDown())减一，await()方法阻塞 线程。等其他线程完成后才执行自己的任务。 类似需求。比如 一场跑步比赛 ………….同时出发.到终点才结束.</p>
<pre><code> public static void main(String[] args) throws Exception&#123;
        ExecutorService executorService = Executors.newFixedThreadPool(10);
//
        CountDownLatch count = new CountDownLatch(2);
        for (int i = 1; i &lt;3 ; i++) &#123;
            Future&lt;Integer&gt; submit = executorService.submit(new doOneThing(i*1000,count));
          //  submit.get();
        &#125;
        System.out.println(&quot;等待子线程完成&quot;);
        count.await(); //  这边会等待所有子线程跑完才会执行
        System.out.println(&quot;###等待子线程完毕&quot;);
        executorService.shutdown();
    &#125;
public static class doOneThing implements Callable&lt;Integer&gt;&#123;
        int i=0;
    CountDownLatch count=null;
        public doOneThing(int i,CountDownLatch count)&#123;
            super();
            this.i=i;
            this.count=count;
        &#125;
    @Override
    public Integer call() throws Exception &#123;

        System.out.println(&quot;###########开始做第&quot;+i/1000+&quot;件事开始&quot;);
        Thread.sleep(i);
        System.out.println(&quot;###########开始做第&quot;+i/1000+&quot;件事完成&quot;);
        count.countDown();
        System.out.println(count.getCount());
        return i;
    &#125;
&#125;
    结果：
    等待子线程完成
    ###########开始做第2件事开始
    ###########开始做第1件事开始
    ###########开始做第1件事完成
    1
    ###########开始做第2件事完成
    0
    ###等待子线程完毕

    await()方法前 所有任务跑完后才会继续执行主线程
</code></pre>
<p>CyclicBarrier 和CountDownLatch 类似,字面意思:环栅栏,通过它可以实现一组线程等待至同一状态之后再同步执行,释放后 CyclicBarrier 可以重用.有点像 countDownLatch 的重用版本<br>特点: synchronization  ,useful for fixedThread occasionally wait each other, re-used</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line">public static void main(String[] args) throws Exception&#123;</span><br><span class="line">        ExecutorService executorService &#x3D; Executors.newFixedThreadPool(10);</span><br><span class="line">&#x2F;&#x2F;</span><br><span class="line">        CyclicBarrier cyclicBarrier &#x3D; new CyclicBarrier(2);</span><br><span class="line"></span><br><span class="line">           executorService.submit(new doOneThing(3*1000,cyclicBarrier));</span><br><span class="line">     executorService.submit(new doOneThing(5*1000,cyclicBarrier));</span><br><span class="line">        executorService.shutdown();</span><br><span class="line">    &#125;</span><br><span class="line">public static class doOneThing implements Callable&lt;Integer&gt;&#123;</span><br><span class="line">        int i&#x3D;0;</span><br><span class="line">    CyclicBarrier cyclicBarrier&#x3D;null;</span><br><span class="line">        public doOneThing(int i,CyclicBarrier cyclicBarrier)&#123;</span><br><span class="line">            super();</span><br><span class="line">            this.i&#x3D;i;</span><br><span class="line">            this.cyclicBarrier&#x3D;cyclicBarrier;</span><br><span class="line">        &#125;</span><br><span class="line">    @Override</span><br><span class="line">    public Integer call() throws Exception &#123;</span><br><span class="line"></span><br><span class="line">        System.out.println(&quot;###########开始做第&quot;+i&#x2F;1000+&quot;件事开始&quot;);</span><br><span class="line">        Thread.sleep(i);</span><br><span class="line">        System.out.println(&quot;###########开始做第&quot;+i&#x2F;1000+&quot;件事完成&quot;);</span><br><span class="line">        cyclicBarrier.await();</span><br><span class="line">        System.out.println(&quot;####当前任务&quot;+i&#x2F;1000+&quot;完成,继续处理其他事情&quot;);</span><br><span class="line">        return i;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">###########开始做第5件事开始</span><br><span class="line">###########开始做第3件事开始</span><br><span class="line">###########开始做第3件事完成</span><br><span class="line">###########开始做第5件事完成</span><br><span class="line">####当前任务5完成,继续处理其他事情</span><br><span class="line">####当前任务3完成,继续处理其他事情</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">可以看到  最后一个print打印 需要等所有任务都完成后.跟CountDownLatch 一样</span><br><span class="line"></span><br><span class="line">可重用  验证  以下为重用,只是把方法复制一遍,就执行了2遍,谁先执行,后面就要等待</span><br><span class="line"></span><br><span class="line">        executorService.submit(new doOneThing(3*1000,cyclicBarrier));</span><br><span class="line">        executorService.submit(new doOneThing(5*1000,cyclicBarrier));</span><br><span class="line">        System.out.println(&quot;开始重用&quot;);</span><br><span class="line">        executorService.submit(new doOneThing(2*1000,cyclicBarrier));</span><br><span class="line">        executorService.submit(new doOneThing(4*1000,cyclicBarrier));</span><br><span class="line">        </span><br><span class="line">       日志:</span><br><span class="line">        开始重用</span><br><span class="line">        ###########开始做第3件事开始</span><br><span class="line">        ###########开始做第5件事开始</span><br><span class="line">        ###########开始做第2件事开始</span><br><span class="line">        ###########开始做第4件事开始</span><br><span class="line">        ###########开始做第2件事完成</span><br><span class="line">        ###########开始做第3件事完成</span><br><span class="line">        ####当前任务3完成,继续处理其他事情</span><br><span class="line">        ####当前任务2完成,继续处理其他事情</span><br><span class="line">        ###########开始做第4件事完成</span><br><span class="line">        ###########开始做第5件事完成</span><br><span class="line">        ####当前任务5完成,继续处理其他事情</span><br><span class="line">        ####当前任务4完成,继续处理其他事情</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<pre><code> Semaphore  可计数的锁.
 构造  public Semaphore(int permits)  同时允许多少线程进行
       public Semaphore(int permits,boolean fair) fair 表示是否公平
      重要的方法 
      acquire();  获取(多个)锁
      release (); 释放(多个)锁
      tryAcquire();尝试获取锁</code></pre>
<pre><code>public static void main(String[] args) throws Exception&#123;
        ExecutorService executorService = Executors.newFixedThreadPool(10);
//
        Semaphore semaphore=new Semaphore(1);
        executorService.submit(new doOneThing(3*1000,semaphore));
        executorService.submit(new doOneThing(5*1000,semaphore));
        executorService.shutdown();
    &#125;
public static class doOneThing implements Callable&lt;Integer&gt;&#123;
        int i=0;
    Semaphore semaphore=null;
        public doOneThing(int i,Semaphore semaphore)&#123;
            super();
            this.i=i;
            this.semaphore=semaphore;
        &#125;
    @Override
    public Integer call() throws Exception &#123;
        semaphore.acquire();
        System.out.println(&quot;###########开始做第&quot;+i/1000+&quot;件事开始&quot;);
        Thread.sleep(i);
        System.out.println(&quot;###########开始做第&quot;+i/1000+&quot;件事完成&quot;);
        semaphore.release();
        System.out.println(&quot;####当前任务&quot;+i/1000+&quot;完成,继续处理其他事情&quot;);
        return i;
    &#125;
    ###########开始做第5件事开始
    ###########开始做第5件事完成
    ####当前任务5完成,继续处理其他事情
    ###########开始做第3件事开始
    ###########开始做第3件事完成
    ####当前任务3完成,继续处理其他事情

    从日志可以看到,如果只有一个锁,会先后执行</code></pre>

    </div>

    
    
    

      <footer class="post-footer">

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2020/09/24/spring-%E6%A0%A1%E9%AA%8C%E6%A1%86%E6%9E%B6%E6%95%B4%E7%90%86/" rel="prev" title="spring-校验框架整理">
      <i class="fa fa-chevron-left"></i> spring-校验框架整理
    </a></div>
      <div class="post-nav-item">
    <a href="/2020/09/24/springBeanpostProcess%E7%9A%84%E7%AE%80%E5%8D%95%E4%BB%8B%E7%BB%8D/" rel="next" title="springBeanpostProcess的简单介绍">
      springBeanpostProcess的简单介绍 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#java-8-%E6%96%B0%E7%89%B9%E6%80%A7completableFuture-%E5%BC%82%E6%AD%A5%E7%BC%96%E7%A8%8B%EF%BC%88%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%B9%B6%E5%8F%91%EF%BC%89"><span class="nav-number">1.</span> <span class="nav-text">java 8 新特性completableFuture 异步编程（多线程并发）</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#completableFutrue-%E7%89%B9%E6%80%A7"><span class="nav-number">1.1.</span> <span class="nav-text">completableFutrue 特性</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#completablefuture-%E6%8B%A5%E6%9C%89-%E4%BB%A5%E4%B8%8B%E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95"><span class="nav-number">1.2.</span> <span class="nav-text">completablefuture 拥有 以下静态方法</span></a></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">wwwttttj</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">8</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://gitee.com/wwwttttj" title="gitee → https:&#x2F;&#x2F;gitee.com&#x2F;wwwttttj" rel="noopener" target="_blank"><i class="fab fa-gitee fa-fw"></i>gitee</a>
      </span>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">wwwttttj</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Gemini</a> 强力驱动
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  















  

  

</body>
</html>
